/******************************************************************************
 * Copyright (C) 2011 ShenZhen ComTop Information Technology Co.,Ltd
 * All Rights Reserved.
 * 本软件为深圳康拓普开发研制。未经本公司正式书面同意，其他任何个人、团体不得使用、
 * 复制、修改或发布本软件.
 *****************************************************************************/

package com.code.common.nosql;

import java.io.IOException;
import java.util.List;

import org.apache.commons.lang.StringUtils;
import org.bson.types.ObjectId;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.code.common.exception.UtilException;
import com.mongodb.BasicDBObject;
import com.mongodb.DB;
import com.mongodb.DBAddress;
import com.mongodb.DBCollection;
import com.mongodb.DBCursor;
import com.mongodb.DBObject;
import com.mongodb.Mongo;
import com.mongodb.MongoException;

/**
 * NOSQL数据库服务
 * 
 * @author 郑重
 * @since 1.0
 * @version 2010-10-28 郑重
 */
public class MongoDBService {

	/**
	 * 日志
	 */
	private static final Logger LOGGER = LoggerFactory.getLogger(MongoDBService.class);

	/**
	 * Mongo db对象
	 */
	private DB db;

	/**
	 * 构造方法
	 * 
	 * @param url mongodb URL
	 * @param port 端口号
	 * @param database 数据库名
	 * @param userName 数据库用户名
	 * @param password 数据库密码
	 */
	public MongoDBService(String host, int port, String database, String userName, String password) {
		try {
			DBAddress objDBAddress = new DBAddress(host, port, database);
			db = Mongo.connect(objDBAddress);
			if (StringUtils.isNotBlank(userName)) {
				db.authenticate(userName, password.toCharArray());
			}
		} catch (IOException e) {
			LOGGER.error("创建MongoDBService出错", e);
		}
	}

	/**
	 * 构造方法
	 * 
	 * @param url mongodb URL
	 * @param port 端口号
	 * @param database 数据库名
	 * @param userName 数据库用户名
	 * @param password 数据库密码
	 */
	public MongoDBService(String host, String database, String userName, String password) {
		try {
			DBAddress objDBAddress = new DBAddress(host, database);
			db = Mongo.connect(objDBAddress);
			if (StringUtils.isNotBlank(userName)) {
				db.authenticate(userName, password.toCharArray());
			}
		} catch (IOException e) {
			LOGGER.error("创建MongoDBService出错", e);
		}
	}

	/**
	 * 关闭连接
	 */
	public void close() {
		db.getMongo().close();
	}

	/**
	 * 根据参数数组对象批量删除对象
	 * 
	 * @param tableName 表名
	 * @param ids 主键对象
	 */
	public void deleteByIds(String tableName, String[] ids) {
		for (String strId : ids) {
			deletebyId(tableName, strId);
		}
	}

	/**
	 * 
	 * 获取collection
	 * 
	 * @param collection
	 * @return
	 */
	public DBCollection getCollection(String collection) {
		return db.getCollection(collection);
	}

	/**
	 * 根据实体对象删除数据
	 * 
	 * @param tableName 表名
	 * @param id 主键编号
	 */
	public void deletebyId(String tableName, String id) {
		DBObject objQuery = new BasicDBObject();
		objQuery.put("_id", new ObjectId(id));
		DBCollection objDBCollection = db.getCollection(tableName);
		objDBCollection.remove(objQuery);
	}

	/**
	 * 根据参数对象删除数据
	 * 
	 * @param tableName 表名
	 * @param mongoDBQuery 查询条件
	 */
	public void delete(String tableName, MongoDBQuery mongoDBQuery) {
		try {
			DBObject objDBObject = nullToDBObject(mongoDBQuery.getQueryConditon());
			DBCollection objDBCollection = db.getCollection(tableName);
			objDBCollection.remove(objDBObject);
		} catch (MongoException e) {
			throw new UtilException("删除对象异常:" + tableName + ":" + mongoDBQuery, e);
		}
	}

	/**
	 * 
	 * 查询所有集合
	 * 
	 * @param tableName
	 * @return
	 */
	public List<DBObject> find(String tableName, MongoDBQuery mongoDBQuery) {
		DBCollection objDBCollection = db.getCollection(tableName);
		DBCursor objDBCursor = objDBCollection.find(mongoDBQuery.getQueryConditon());
		if (objDBCursor != null) {
			return objDBCursor.toArray();
		} else {
			return null;
		}
	}

	/**
	 * 查询记录数
	 * 
	 * @param <T> 实体类型
	 * @param tableName 表名
	 * @param mongoDBQuery 参数对象
	 * @return 返回结果
	 */
	public <T> long getCount(String tableName, MongoDBQuery mongoDBQuery) {
		try {
			DBObject objDBObject = nullToDBObject(mongoDBQuery.getQueryConditon());
			DBCollection objDBCollection = db.getCollection(tableName);
			return objDBCollection.getCount(objDBObject);
		} catch (MongoException e) {
			throw new UtilException("查询记录数异常:" + tableName + ":" + mongoDBQuery, e);
		}
	}

	/**
	 * null转DBObject
	 * 
	 * @param dbObject DBObject
	 * @return object
	 */
	private DBObject nullToDBObject(DBObject dbObject) {
		if (dbObject == null) {
			return new BasicDBObject();
		}
		return dbObject;
	}

}
